MENTAL Y LA UNIÓN DE
HARDWARE Y
SOFTWARE


La Unión de Hardware y Software

Es lógico plantearse la posibilidad de la unificación de hardware y software y sobre la naturaleza de esa unión.

Decir hardware, como su nombre indica, es decir rigidez. Y decir software es decir flexibilidad. De hecho el software se inventó para flexibilizar un diseño hardware. En los primeros tiempos de los ordenadores, cambiar un programa suponía cambiar las conexiones de la circuitería de la máquina. El gran salto evolutivo fue la idea de almacenar el código del programa en memoria, junto con los datos. Esto tenía varias ventajas: El hardware ha evolucionado para dar soporte a ciertos aspectos de la programación, como la modularización, la programación estructurada, el multiproceso, la memoria virtual, etc.

Es evidente que la dependencia del software respecto al hardware debería ser la mínima posible, pues a menor dependencia del hardware, mayor es la flexibilidad. Además, siempre se ha planteado el tema del diseño del procesador ideal y del lenguaje ideal, así como de la forma de interacción entre ambos.

Para hacer flexible un procesador se ha utilizado microcódigo programable, un código basado en instrucciones de muy bajo nivel (microinstrucciones). Esta tecnología ya ha desaparecido por completo porque existen herramientas avanzadas para diseñar complejas unidades de control que tienen un rendimiento significativamente mayor que cualquier unidad microprogramada.


La dualidad código fuente - código de máquina

En los sistemas convencionales, el hardware del ordenador no puede ejecutar directamente el programa fuente del usuario. Se necesita un compilador o intérprete que transforme el programa fuente en código objeto, el código binario o código de máquina ejecutable por el hardware. Los problemas de este proceso son: 1) su coste computacional (tiempo de proceso y recursos de máquina); 2) ineficiencia, porque el código objeto no suele ser óptimo o es poco adecuado; 3) la generación de errores de compilación, porque los compiladores son difíciles de desarrollar; 4) los mensajes de error durante la ejecución suelen ser crípticos porque se expresan en el lenguaje de bajo nivel de la máquina, y no en el lenguaje de alto nivel del usuario.

La compatibilidad binaria ha sido un problema desde el comienzo de los lenguajes de programación, pues el código binario liga el software a un hardware particular. Para reducir o eliminar este problema, se han propuesto básicamente dos soluciones:
  1. El desarrollo de “máquinas virtuales”, máquinas intermediarias entre el hardware real y el programa a ejecutar.

  2. El desarrollo de procesadores orientados a un lenguaje determinado, con el fin de optimizar el rendimiento al haber un interfaz homogéneo entre software y hardware.

Las máquinas virtuales

Las máquinas virtuales utilizan un juego de instrucciones abstracto, no perteneciente a ninguna máquina específica. Un compilador genera un código abstracto en ese lenguaje abstracto y la máquina virtual interpreta y ejecuta ese código abstracto. La ventaja del código abstracto es su portabilidad: el mismo código puede ser ejecutado por diferentes plataformas. El código abstracto es muy compacto, por lo que el rendimiento es mayor. Para que ese código objeto sea posible es necesario desarrollar una máquina virtual en cada plataforma hardware. La máquina virtual se puede usar como un sistema operativo completo o ejecutarse bajo otro sistema operativo.

Hay dos formatos de código abstracto para máquina virtual: bytecode y p-code. Java y Smalltalk utilizan bytecode. UCSD Pascal utiliza p-code.

Una máquina virtual Java es una máquina virtual capaz de interpretar y ejecutar instrucciones expresadas en el bytecode Java, el código binario generado por el compilador del lenguaje Java. La máquina virtual Java actúa como intermediario entre el hardware y el bytecode. Existen diferentes máquinas virtuales Java para diferentes arquitecturas hardware.

La máquina virtual Smalltalk −el primer lenguaje orientado a objetos− es una máquina virtual que permite que una imagen Smalltalk (fichero bytecode) se ejecute bajo una plataforma. El nombre de “imagen” hace referencia a que una imagen de la memoria interna de la máquina se graba en memoria externa (disco). Los objetos Smalltalk “sobreviven” tras finalizar la ejecución.

UCSD Pascal es un lenguaje de programación que funciona sobre el UCSD p-System, un sistema operativo independiente de la máquina, que se calificó en su día como “sistema operativo universal”. UCSD Pascal tuvo una gran influencia en la máquina virtual Smalltalk y en el diseño de la máquina virtual Java.

La máquina virtual de UCSD p-System se denomina “p-machine” (o psedo-machine), con su propio juego de instrucciones llamado p-code (o pseudo-code). Cada plataforma hardware solo necesita un intérprete de p-code para portar el sistema entero p-System y todas sus herramientas.


Procesadores orientados a un lenguaje de programación

Las ventajas de la unificación entre hardware y software mediante un procesador orientado a un lenguaje de programación son:
La Evolución de los Procesadores

Los procesadores han ido evolucionando a lo largo de la historia de la informática. Desde los procesadores complejos, rígidos y restrictivos, pasando por los simplificados y llegando hasta los minimalistas, siempre en el sentido de una mayor simplicidad, flexibilidad y eficiencia. La evolución ha sido la siguiente:


CISC (Complex Instruction Set Computer)

Fueron los primeros procesadores. Su nombre se lo asignaron los partidarios de procesadores más reducidos y simples (los RISC). Los procesadores CISC implementan un conjunto muy amplio de instrucciones complejas, con operandos situados en la memoria o en registros internos de la máquina.

En los primeros tiempos de los ordenadores, la tecnología de compilación no existía. La programación se tenía que realizar en lenguaje ensamblador. Para facilitar la tarea del programador, se crearon instrucciones complejas, que eran como las funciones de los lenguajes de programación de alto nivel. Esto condujo a procesadores cada vez más complejos y sofisticados. Cuando aparecieron los compiladores, en los que una instrucción de alto nivel se podía implementar en varias instrucciones elementales, ya no era necesario hace esto, por lo que se podía simplificar el hardware.


RISC (Reduced Instruction Set Computer)

Los procesadores RISC se crearon para mejorar el rendimiento de los procesadores CISC. Para ello se simplificó el diseño: Hoy día, la gran mayoría de los procesadores son RISC.


MISC (Minimal Instruction Set Computer)

Es un procesador con un número muy pequeño de instrucciones. Está basado en una pila, en lugar de registros para reducir el tamaño de los operandos, pues todas las instrucciones toman los operandos de lo más alto de la pila. Normalmente, un MISC consta 32 instrucciones como máximo.

Las ventajas son que la unidad de decodificación (interpretación del código) es más simple y rápida, y las instrucciones son más eficientes.


OISC (One Instruction Set Computer)

Es una máquina teórica (o abstracta) que tiene solo una instrucción pero con mayor número de operandos. Las instrucción elegida suele ser del tipo “Restar y bifurcar si condición”. La condición suele ser “menor o igual que cero”, “negativo” o “distinto de cero”. Si no se cumple la condición, la ejecución pasa a la instrucción siguiente. Ejemplos: Características: Ejemplos de instrucciones derivadas de Sbnz:
VLIW (Very Long Instruction Word)

Es una arquitectura de procesador diseñada para aprovecharse del paralelismo a nivel de instrucción. Es tarea del compilador el controlar la planificación de las instrucciones y la protección de los datos.


NISC (No Instruction Set Computer)

Los procesadores NISC son los sucesores de los VLIW. Es una arquitectura de procesador altamente eficiente que permite a un compilador tener un control de bajo nivel de los recursos hardware. Tiene control horizontal (la secuencia de las instrucciones) y vertical (el paralelismo de las instrucciones). La arquitectura es mucho más simple (pues no se necesita decodificar las instrucciones), más flexible y eficiente.


ZISC (Zero Instruction Set Computer)

Es un procesador sin instrucciones. Incorpora en su lugar una tecnología orientada a reconocimiento de patrones (pattern matching), por lo que no tienen instrucciones en el sentido clásico. Está basada en las ideas de las redes neuronales artificiales y en el proceso masivamente paralelo.

La primera generación de un chip ZISC contenía 36 células independientes, en donde cada célula se puede considerar como una neurona artificial o un procesadores paralelo. Cada célula puede comparar un vector de entrada de hasta 64 bytes con otro vector en memoria. Si el vector de entrada coincide con el vector de la memoria, las células emiten una señal de salida que contiene el número de la célula que ha reconocido el vector o una señal de no reconocimiento.

El poder de un ZISC reside en la escalabilidad. Una red ZISC se puede expandir añadiendo más procesadores ZISC sin que decrezca su velocidad de reconocimiento. Y no hay limitación teórica respecto al número de células que puede haber en una red.

Los chips ZISC se pueden utilizar también para hacer reconocimientos difusos (fuzzy). En lugar de un reconocimiento exacto, se puede obtener el reconocimiento más próximo. Las células que están por encima de un cierto umbral se disparan simultáneamente y el controlador ZISC localiza la célula que devuelve el valor más próximo.


Procesadores Orientados a Lenguajes de Programación

Existen antecedentes de implementación sobre hardware de un lenguaje de programación. Los más destacados son los siguientes:


Rekursiv

Rekursiv fue un microprocesador orientado a objetos desarrollado diseñado por David M. Harland (de la Universidad de Glasgow) a mediados de los años 1980’s para la empresa Linn Smart (Glasgow) para controlar su sistema de fabricación de equipos Hi-Fi. La motivación principal fue la mejora del rendimiento de Lingo, un lenguaje orientado a objetos (derivado de Smalltalk y Algol), también desarrollado por la misma empresa, que no era satisfactorio con el hardware de su época (Digital Vax). En aquella época no era muy conocido aún el paradigma objetual, por lo que tuvo bastante mérito embarcarse en esa aventura. El procesador era realmente innovador y fue sorprendentemente fácil de implementar. El proyecto finalmente se abandonó porque Linn no tenía recursos suficientes para proseguir con esa prometedora arquitectura. Pero demostró la viabilidad de construcción de procesadores de alto nivel de abstracción de hardware para acercarlos a los lenguajes orientados a objetos.


Procesadores Forth

Forth es un lenguaje simple y eficiente, desarrollado por Chuck Moore y Elisabeth Rather entre los años 1965 y 1970, para aplicaciones astronómicas en tiempo real, pero que evolucionó hasta convertirse en un lenguaje de programación general y en un entorno de programación. Actualmente se usa principalmente para programar sistemas empotrados (pequeños dispositivos computerizados) y cargadores (boot loaders). Ls procesadores Forth usan Forth como lenguaje de máquina. Los procesadores de pila (stack computers) están inspirados en el lenguaje Forth. Las ventajas de estos procesadores son: Los procesadores Forth y de pila han tenido menor difusión que las máquinas tradicionales de registros.


Procesadores Lisp

Un procesador Lisp (o Lisp machine) es un procesador de propósito general y de alto nivel de abstracción diseñado para ejecutar eficientemente código Lisp. Lisp es un lenguaje de inteligencia artificial de tipo funcional y uno de los más utilizados por su extraordinaria flexibilidad. La máquina Lisp estaba orientada al desarrollo y ejecución de aplicaciones de inteligencia artificial. Las máquinas Lisp fueron las primeras estaciones de trabajo orientadas a un solo usuario. Muchas tecnologías hoy comunes, como los interfaces gráficos de usuario y el uso del ratón, fueron desarrolladas originalmente en máquinas Lisp.

Con la aparición de los ordenadores personales, las máquinas Lisp prácticamente desaparecieron. Solo han sobrevivido dos: Symbolics y Macrosyma.


Procesadores Java

La empresa Sun introdujo Java Virtual Machine (JVM), una capa software sobre una plataforma hardware para el desarrollo y la ejecución de programas Java.

Ha habido varios intentos de construir un procesador que interpretara directamente el bytecode Java como su lenguaje de máquina, pero todos los intentos en este sentido fueron infructuosos. Quizás el fracaso se debió a la complejidad de Java. Un procesador debe ser lo más simple posible.


La Unión Hardware-Software en MENTAL

Con MENTAL se unen todas las dualidades a nivel conceptual. La última dualidad a superar es el tema implementador: unir hardware y software. Que hardware y software hablen el mismo lenguaje: que el conjunto de primitivas semánticas universales sea también el juego de instrucciones del hardware.

De la misma forma que con las primitivas semánticas universales hemos alcanzado las raíces conceptuales de la programación, debemos reflejar esa misma esencia en el hardware para conseguir la máxima homogeneidad, coherencia y eficiencia.

Sería el hardware “ideal”, como MENTAL es el lenguaje ideal. El “juego de instrucciones” de un ordenador (o máquina abstracta) universal (o de propósito general), una máquina más general que la máquina de Turing, pues es operativa y descriptiva.

Si esto fuera posible tendríamos muchas ventajas:

Adenda

MENTAL vs. Forth

Existen numerosas coincidencias entre Forth y MENTAL en los siguientes aspectos:
Bibliografía